﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StaticPlugin;
using System.Windows.Forms;

namespace MosWar
{
    class jGrabZakoulki : AJob
    {
        #region Interface with executer

        public override bool testRequirements(WebBrowser b)
        {
            if (actions.Count > 0) return true;
            if (b.Document == null)
            {
                busy = false;
                return false;
            }
            if (b.Document.Body == null)
            {
                busy = false;
                return false;
            }
            if (b.IsBusy)
            {
                return false;
            }
            //HtmlElement HeaderLinks = WebParserEx.getTagByClassName(b.Document.Body, "div", "header clear");
            //if (HeaderLinks == null)
            //{
            //    Console.WriteLine("jGrabZakoulki::testRequirements=false");
            //    return false;
            //}
            //HtmlElement timeouts = HeaderLinks.GetElementsByTagName("a")["timeout"];
            //if (timeouts != null) 
            //{
            //    string to_reason = timeouts.GetAttribute("href");
            //    if (to_reason == b.Url.Scheme + "://" + b.Url.Host + "/alley/" || to_reason == b.Url.Scheme + "://" + b.Url.Host + "/metro/")
            //    {
            //        TimeSpan ts = TimeSpan.FromSeconds(double.Parse(timeouts.GetAttribute("timer")));
            //        if (ts.TotalSeconds > 0)
            //        {
            //            timeToActivate = DateTime.Now;
            //            timeToActivate = timeToActivate.Add(ts);
            //            busy = true;
            //            return false;
            //        }
            //    }
            //}
            DateTime timeToActivate = DateTime.Now;
            string timeoutUrl = "";
            SkillsDetector.GetMainTmeoutStatus(b, out timeToActivate, out timeoutUrl);
            int skills = SkillsDetector.getHeath(b);
            //bool z = timeToActivate <= DateTime.Now;

            //if (false) // (timeouts == null)
            //{
            //    Console.WriteLine("jGrabZakoulki::testRequirements=true");
            //    busy = false;
            //    return true; // если нет таймаутов
            //}

            if (timeToActivate > DateTime.Now) 
            {
                string stwork = "Отдых от боев ";
                if (timeoutUrl == "http://www.moswar.ru/shaurburgers/") stwork = "Работа в шаурме ";
                status = stwork + "до " + timeToActivate.ToShortTimeString();
                return false;
            }
            
            if (skills < 50 && SkillsDetector.getMoney(b) > setup.минДенегДляЛечения.Value)
            {
                actions.Clear();
                actions.Add(new Action("", NavigateToHata));
                actions.Add(new Action("", GetMidicalAssistance));
                return true;
            }
            //Console.WriteLine("jGrabZakoulki::testRequirements(last). skills=" + z.ToString());
            if (timeoutUrl != "http://www.moswar.ru/shaurburgers/")
            {
                FillActionsToFight();
                return true;
            }
            return false;
        }

        private void FillActionsToFight()
        {
            actions.Clear();

            actions.Add(new Action("Идем в закоулки на грабеж", NavigateToAlley));
            actions.Add(new Action("Поиск соперника", FindPersonToFight));
            actions.Add(new Action("Запуск боя", startFight2));
            actions.Add(new Action("Переход к результатам боя", forceFight));
            actions.Add(new Action("Анализ боя", analyzeFight));
        }

        public override DialogResult showSetupDialog()
        {
            return setup.ShowDialog();
        }

        public void GetMidicalAssistance(WebBrowser b) 
        {
            busy = false;
            HtmlElement home_medicine = WebParserEx.getTagByClassName(b.Document.Body, "form", "home-medicine");
            if (home_medicine == null) 
            {
                status = "Не смогли перейти в хату для лечения";
                actions.Clear();
                return;
            }
            HtmlElement btnHeal = WebParserEx.getTagByClassName(home_medicine, "div", "button");
            if (btnHeal == null)
            {
                status = "Не смогли найти кнопку лечения";
                actions.Clear();
                return;
            }
            status = "Лечимся";
            log(" >>> Мало жизней - Лечимся в хате");
            btnHeal.InvokeMember("click");
        }
        
        public void NavigateToHata(WebBrowser b) 
        {
            if (b.Url.AbsolutePath != "/home/") b.Navigate("www.moswar.ru/home/");
            status = "Идем в хату";
        }
        
        public override void initActions()
        {

        }

        protected override string getName()
        {
            return "Грабежи в закоулках";
        }

        protected override string getStatus()
        {
            //status = "Idle";
            if (busy)
            {
                status = "Активация планируется в '" + timeToActivate.ToShortTimeString() + "'";
            }
            return status;
        }

        protected override bool getAvailable()
        {
            return (bool)Properties.Settings.Default["cbActiveGrabZakoulki"];
        }

        protected override int getPriority()
        {
            int i;
            try
            {
                i = int.Parse(Properties.Settings.Default["GrabZakoulkiPriority"].ToString());
            }
            catch (Exception)
            {
                return 100;
            }
            return i;
        }

        #endregion

        DateTime timeToActivate = DateTime.Now;
        bool busy = false;
        string status = "Idle";
        jGrabZakoulkiSetup setup = new jGrabZakoulkiSetup();

        void log(string s)
        {
            Properties.Settings.Default["edLogFightWindow"] = Properties.Settings.Default["edLogFightWindow"].ToString() + Environment.NewLine + s;
            Properties.Settings.Default.Save();
        }

        #region Actions

        int tryToFindLowLevelPerson = -1;

        void NavigateToAlley(WebBrowser b)
        {
            tryToFindLowLevelPerson = 0;
            if (b.Url.AbsolutePath != "/alley/") b.Navigate("www.moswar.ru/alley/");
            status = "Идем в закоулки на грабеж";
        }

        void FindPersonToFight(WebBrowser b)
        {
            if (b.Url.AbsolutePath != "/alley/")
            {
                status = "Не смогли перейти в закоулки!";
                actions.Clear();
                return;
            }
            status = "Поиск соперника";
            HtmlElement frmSearchAlley = WebParserEx.getTagByClassName(b.Document.Body, "form", "search-alley");
            HtmlElement opponentType = WebParserEx.getTagByName(frmSearchAlley, "select", "type");
            HtmlElement btnFindAlley = WebParserEx.getTagByClassName(frmSearchAlley, "div", "button");
            HtmlElement timerToRest = WebParserEx.getTagByClassName(frmSearchAlley, "p", "timer");

            if (timerToRest != null)
            {
                busy = true;
                HtmlElement time = WebParserEx.getTagByClassName(timerToRest, "span", "timer");
                TimeSpan ts = TimeSpan.FromSeconds(double.Parse(time.GetAttribute("timer")));
                if (ts.TotalSeconds > 0)
                {
                    timeToActivate = DateTime.Now;
                    timeToActivate = timeToActivate.Add(ts);
                    actions.Clear();
                    Console.WriteLine("jGrabZakoulki::FindPersonToFight - detected time to rest!");
                    return;
                }
            }

            if (opponentType == null || btnFindAlley == null)
            {
                Console.WriteLine("opponentType or btnFindAlley is null!");
                return; // TODO generate an error
            }

            string s = setup.searchTypes[int.Parse(Properties.Settings.Default["findEnemyType"].ToString())].value;
            opponentType.SetAttribute("value", s);
            btnFindAlley.InvokeMember("click");
        }

        void startFight2(WebBrowser b) 
        {
            HtmlElement fighter1 = WebParserEx.getTagByClassName(b.Document.Body, "div", "fighter1");
            HtmlElement fighter2 = WebParserEx.getTagByClassName(b.Document.Body, "div", "fighter2");
            if (fighter2 == null || fighter1 == null) 
            {
                HtmlElement frmSearchAlley = WebParserEx.getTagByClassName(b.Document.Body, "form", "search-alley");
                HtmlElement frmError = WebParserEx.getTagByClassName(frmSearchAlley, "p", "error");
                if (frmError == null)
                {
                    //throw new Exception("Странная какая-то ошибка!");
                    return;
                }
                log("Ошибка поиска соперника: " + frmError.InnerText);
                return;
                //throw new Exception("Не смогли найти форму с оппонентом или свою");
            }
            string strOpponentName = fighter2.GetElementsByTagName("a")[0].InnerText;
            string strOpponentNameMy = fighter1.GetElementsByTagName("a")[0].InnerText;
            string strOpponentLevel = WebParserEx.getTagByClassName(fighter2, "span", "level").InnerText;
            string strOpponentLevelMy = WebParserEx.getTagByClassName(fighter1, "span", "level").InnerText;
            strOpponentLevel = strOpponentLevel.Replace("[", "").Replace("]", "");
            strOpponentLevelMy = strOpponentLevelMy.Replace("[", "").Replace("]", "");
            int level = -1;
            int myLevel = -1;
            if (!int.TryParse(strOpponentLevel, out level) || !int.TryParse(strOpponentLevelMy, out myLevel)) 
            {
                throw new Exception("cannot parse opponent level or own level!");
            }
            if (level >= myLevel && setup.cbSearchLevelDown.Checked && tryToFindLowLevelPerson <=5 )
            {
                tryToFindLowLevelPerson++;
                actions.Insert(0, new Action("", startFight2));
                log("при поиске обнаружен " + strOpponentName + " с уровнем " + strOpponentLevel + ". пытаемся найти кого-нибудь другого");
                HtmlElement button_search = WebParserEx.getTagByClassName(b.Document.Body, "div", "button button-search").GetElementsByTagName("a")[0];
                button_search.InvokeMember("click");
            }
            else 
            {
                tryToFindLowLevelPerson = 0;
                status = "Запуск боя";
                if (level >= myLevel) log("кончились попытки найти 'мальенького', бьем кого придется - "+strOpponentName);
                else log("Начинаем бить " + strOpponentName + " с уровнем " + strOpponentLevel);
                Console.WriteLine("finded opponent '" + strOpponentName + "', level " + strOpponentLevel + "'");
                HtmlElement button_fight = WebParserEx.getTagByClassName(b.Document.Body, "div", "button button-fight").GetElementsByTagName("a")[0];
                button_fight.InvokeMember("click");
            }
        }

        void startFight(WebBrowser b)
        {
            status = "Запуск боя";
            HtmlElement fighter2 = WebParserEx.getTagByClassName(b.Document.Body, "div", "fighter2");
            if (fighter2 == null) // почему-то не нашли соперника. разбираемся почему
            {
                HtmlElement frmSearchAlley = WebParserEx.getTagByClassName(b.Document.Body, "form", "search-alley");
                if (b.Document.Body.GetElementsByTagName("form").Count == 0)
                {
                    log("не удалось запустить бой");
                    actions.Clear();
                    busy = false;
                    return;
                }
                if (frmSearchAlley == null)
                {
                    throw new Exception("Странная какая-то ошибка!");
                }
                HtmlElement frmError = WebParserEx.getTagByClassName(frmSearchAlley, "p", "error first-child");
                if (frmError == null)
                {
                    throw new Exception("Странная какая-то ошибка!");
                }
                log("Ошибка поиска соперника: " + frmError.InnerText);
                return;
            }

            try
            {
                string opponentName = fighter2.GetElementsByTagName("a")[0].InnerText;
                log("Начинаем бить " + opponentName);
                string opponentLevel = fighter2.GetElementsByTagName("span")[0].InnerText;
                Console.WriteLine("finded opponent '" + opponentName + "', level " + opponentLevel + "'");
                //HtmlElement buttons = WebParserEx.getTagByCLassName(b.Document.Body,"div", "fight-button-block curves");
                HtmlElement button_fight = WebParserEx.getTagByClassName(b.Document.Body, "div", "button button-fight").GetElementsByTagName("a")[0];
                button_fight.InvokeMember("click");
            }
            catch (Exception e)
            {
                Console.WriteLine("someting error!");
                throw e;
            }
        }

        void forceFight(WebBrowser b)
        {
            status = "Переход к результатам боя";
            HtmlElement iconControls = WebParserEx.getTagByClassName(b.Document.Body, "div", "icon controls");
            if (iconControls == null)
            {
                status = "Ошибка поиска кнопок управления скоростью боя";
                actions.Clear();
                return;
            }
            HtmlElement iconForward = iconControls.GetElementsByTagName("i")["controls-forward"];
            if (iconForward == null)
            {
                status = "Ошибка поиска кнопки ускорения боя";
                actions.Clear();
                return;
            }
            iconForward.InvokeMember("click");
        }

        void analyzeFight(WebBrowser b)
        {
            status = "Анализ боя";
            HtmlElement res = WebParserEx.getTagByClassName(b.Document.Body, "li", "result");
            if (res == null)
            {
                log("Ошибка анализа боя!. res=null");
                return;
            }
            HtmlElementCollection forResult = res.GetElementsByTagName("div");
            if (forResult.Count < 2)
            {
                log("бой. результат - ничья!");
            }
            else
            {
                HtmlElement results = forResult[1];
                string winner = results.GetElementsByTagName("b")[0].InnerText;
                string price_money = WebParserEx.getTagByClassName(results, "span", "tugriki").InnerText;
                string price_expa = WebParserEx.getTagByClassName(results, "span", "expa").InnerText;
                string strlog = "бой. победил: " + winner + ", он получил тугриков:" + price_money + " и опыта:" + price_expa;
                log(strlog);
            }
            //Console.WriteLine(strlog);
            b.Navigate("www.moswar.ru/alley");
        }

        #endregion

    }
}
